﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Web;
using WebSite.Models;
using WebSite.Models.BusinessModels;

namespace WebSite.Repositories
{
    public class OnlineChatApplicationRepository:IOnlineChatRepository
    {
        private const string KEY = "onlineSessions";
        private HttpApplicationState _storageHost;

        private class SessionContainer
        {
            public SessionContainer()
            {
                this.Messages  = new List<MeetingMessageVM>();
                this.CreatedOn = SmartTime.Now;
            }

            public  DateTime                            CreatedOn { get; set; }
            public  List<MeetingMessageVM>              Messages { get; set; }
        }

        private Dictionary<Guid, SessionContainer> Strorage
        {
            get
            {
                Dictionary<Guid, SessionContainer> dictionary = _storageHost[KEY] as Dictionary<Guid, SessionContainer>;
                if (dictionary == null)
                {
                    dictionary = new Dictionary<Guid, SessionContainer>();
                    _storageHost.Add(KEY, dictionary);
                }
                return dictionary;
            }
        }

        private SessionContainer LoadSession(Guid guid)
        {
            if (this.Strorage.ContainsKey(guid)){
                return this.Strorage[guid];
            }
            return null;
        }


        public OnlineChatApplicationRepository(HttpApplicationState aspnetApplication)
        {
            _storageHost = aspnetApplication;
        }

        public void DeleteSession(Guid meetingSession)
        {
            if (this.Strorage.ContainsKey(meetingSession))
                this.Strorage.Remove(meetingSession);

        }

        public void ArchiveSession(MeetingSessionVM session, IEnumerable<WebSite.Models.MeetingMessageVM> messages)
        {
            return;
        }

        public MeetingSessionVM CreateMeetingSession(String requestorIP)
        {
            Guid newSessionID = Guid.NewGuid();

            this.Strorage.Add(newSessionID, new SessionContainer());

            return GetMeetingSessionById(newSessionID);
        }

        public IEnumerable<MeetingSessionVM> GetActiveSessions()
        {
            List<MeetingSessionVM> result = new List<MeetingSessionVM>();
            foreach (Guid key in this.Strorage.Keys)
            {
                result.Add(new MeetingSessionVM()
                {
                    LastMessageId = (uint)this.Strorage[key].Messages.Count,
                    SessionId     = key
                });
            }
            return result;
        }

        public MeetingSessionVM GetMeetingSessionById(Guid meetingSession)
        {
            SessionContainer sessionContainer = LoadSession(meetingSession);
            if (sessionContainer == null)
            {
                return null;
            }
            return new MeetingSessionVM()
            {
                LastMessageId = (uint)LoadSessionMessages(meetingSession,0).Count() ,
                SessionId     = meetingSession,
                CreatedOn     = sessionContainer.CreatedOn,
            };
        }

        public IEnumerable<MeetingMessageVM> LoadSessionMessages(Guid session, ulong startingFrom)
        {
            SessionContainer container = LoadSession(session);

            if (container == null)
                throw new ArgumentOutOfRangeException("session");

            List<MeetingMessageVM> sessionMessages = container.Messages;

            return sessionMessages.Skip((int)startingFrom).ToList();
        }

        public MeetingMessageVM AddMessageToSession(Guid session, MeetingMessageVM message)
        {
            if (message == null)
                throw new ArgumentNullException("message");

            if (String.IsNullOrEmpty(message.MessageText))
                throw new ArgumentException("message text is empty");

            SessionContainer container = LoadSession(session);

            if (container  == null)
                throw new ArgumentOutOfRangeException("session");

            List<MeetingMessageVM> sessionMessages = container.Messages;

            message.MessageId = (ulong)(sessionMessages.Count + 1);

            sessionMessages.Add(message);

            return message;
        }


        public bool StartBotProcessing(Guid sessionId)
        {
            throw new NotImplementedException();
        }

        public void EndBotProcessing(Guid sesionId)
        {
            throw new NotImplementedException();
        }
    }
}